import torch

########################
# 自动微分计算模拟真实应用场景
########################


# x表示特征(输入数据), 假设: 2行5列, 全1矩阵.
x = torch.ones(2, 5)
print(f'模拟输入值（全一）: {x}')
print("="*50)
print()

# y表示标签(真实值), 假设: 2行4列, 全0矩阵
y = torch.zeros(2,4)


# 初始化(可自动微分的)权重 和 偏置.
w = torch.randn(5,4,requires_grad=True)

b = torch.randn(4,requires_grad=True)

# 前向转播(正向传播), 计算出 预测值(z).
z = torch.matmul(x, w) + b
print(f'模拟预测值: {z}')
print("="*50)
print()

# 定义损失函数.把真实值和预测值传入
criterion = torch.nn.MSELoss()  # 使用函数neural network: 神经网络
loss = criterion(z, y)          # loss = 损失

print(f'模拟损失值: {loss:5f},损失类型 : {type(loss)}')
print("="*50)
# 进行自动微分, 求导, 结合反向传播, 更新权重.
# loss.sum().backward()

for i in range(1,101):
    # 重新设置损失函数
    z = torch.matmul(x, w) + b
    loss = criterion(z, y)

    if(w.grad is not None):
        w.grad.zero_()
    if(b.grad is not None):
        b.grad.zero_()

    loss.sum().backward()
    # 更新权重
    w.data = w.data - 0.01 * w.grad
    b.data = b.data - 0.01 * b.grad
    print(f'loss: {loss:3f}')


